Skip to content

fix(core): serialize structured tool results as JSON#7922

Open
Oxygen56 wants to merge 1 commit into
microsoft:mainfrom
Oxygen56:fix-structured-tool-result-json
Open

fix(core): serialize structured tool results as JSON#7922
Oxygen56 wants to merge 1 commit into
microsoft:mainfrom
Oxygen56:fix-structured-tool-result-json

Conversation

@Oxygen56

@Oxygen56 Oxygen56 commented Jul 5, 2026

Copy link
Copy Markdown

Summary

  • serialize dict and list tool return values as JSON instead of Python repr strings
  • serialize dataclass tool return values via asdict() before JSON encoding
  • preserve the existing str(value) fallback for non-JSON-serializable values
  • add regression coverage for dict, nested list, dataclass, and fallback behavior

Fixes #7867
Related: #7873

Why this shape

#7873 handles the immediate dict/list case, but this PR also covers dataclass return values and explicitly tests the fallback path for values that cannot be JSON encoded. Scalar/string behavior and the existing BaseModel behavior are unchanged.

Testing

  • /tmp/autogen-pr-test-venv/bin/python -m pytest python/packages/autogen-core/tests/test_tools.py -q (42 passed)
  • uvx ruff check python/packages/autogen-core/src/autogen_core/tools/_base.py python/packages/autogen-core/tests/test_tools.py
  • uvx ruff format --check python/packages/autogen-core/src/autogen_core/tools/_base.py python/packages/autogen-core/tests/test_tools.py

Note: I first tried the full workspace command uv run --directory python/packages/autogen-core pytest tests/test_tools.py -q, but local dependency downloads repeatedly retried and did not complete. The package-level isolated environment above verifies this change without pulling the full workspace dev stack.

@ErenAta16 ErenAta16 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran the full new test set on the branch (installed autogen-core in editable mode to make sure I was actually exercising the local changes, not a stale pinned release) — 6 passed, covering dict, nested list, dataclass, and the non-serializable fallback.

This overlaps with #7932, which is also open and touches the exact same lines in return_value_as_string. Compared the two: this one is a strict superset — same dict/list JSON handling, plus the asdict() pass for dataclass return values and an explicit fallback test, which #7932 does not cover. Both are correct as far as they go; this one is just more complete. Flagging the duplication so only one lands — happy to see either merged, just did not want the overlap to go unnoticed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: ToolCallResult auto-coerces structured tool outputs to str(), losing type information

2 participants